core: Don't strip setuid bits when creating files
authorColin Walters <walters@verbum.org>
Thu, 18 Jul 2013 18:23:55 +0000 (14:23 -0400)
committerColin Walters <walters@verbum.org>
Thu, 18 Jul 2013 18:23:55 +0000 (14:23 -0400)
This ugly regression occurred because I overlooked the fact that our
chown() invocation would strip off setuid.

Makefile-tests.am
src/libgsystem
src/libostree/ostree-core.c
tests/test-setuid.sh [new file with mode: 0755]

index 7485784ca0b9b9016da45767b5ca669d465936eb..19764e66b56f2dd07c2779eae3e88df788ec0877 100644 (file)
@@ -31,6 +31,7 @@ testfiles = test-basic \
        test-pull-corruption \
        test-admin-deploy-1 \
        test-admin-deploy-2 \
+       test-setuid \
        $(NULL)
 insttest_SCRIPTS = $(addprefix tests/,$(testfiles:=.sh))
 
index 939cd18d39b1abf39543c83c406246b12dbfa03a..f56702ef40a5df056097d2e14ee0dac3614b744c 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 939cd18d39b1abf39543c83c406246b12dbfa03a
+Subproject commit f56702ef40a5df056097d2e14ee0dac3614b744c
index 99bc84da64a0d6abf0fe95ec986c7dc1a08d378e..ef9595d4396c58d326eb936015ba1b2e172fa996 100644 (file)
@@ -1220,9 +1220,21 @@ ostree_create_file_from_input (GFile            *dest_file,
     }
   else if (S_ISREG (mode))
     {
-      if (!gs_file_create (dest_file, mode, &out,
-                           cancellable, error))
-        goto out;
+      if (finfo != NULL)
+        {
+          uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
+          gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
+
+          if (!gs_file_create_with_uidgid (dest_file, mode, uid, gid, &out,
+                                           cancellable, error))
+            goto out;
+        }
+      else
+        {
+          if (!gs_file_create (dest_file, mode, &out,
+                               cancellable, error))
+            goto out;
+        }
 
       if (input)
         {
@@ -1250,7 +1262,10 @@ ostree_create_file_from_input (GFile            *dest_file,
       goto out;
     }
 
-  if (finfo != NULL)
+  /* We only need to chown for directories and symlinks; we already
+   * did a chown for files above via fchown().
+   */
+  if (finfo != NULL && !S_ISREG (mode))
     {
       uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
       gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
diff --git a/tests/test-setuid.sh b/tests/test-setuid.sh
new file mode 100755 (executable)
index 0000000..02aa9f6
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+# Copyright (C) 2013 Colin Walters <walters@verbum.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+set -e
+
+echo "1..1"
+
+. $(dirname $0)/libtest.sh
+
+setup_test_repository "bare"
+
+cd ${test_tmpdir}
+cat > test-statoverride.txt <<EOF
++2048 /abinary
+EOF
+$OSTREE checkout test2 test2-checkout
+touch test2-checkout/abinary
+chmod a+x test2-checkout/abinary
+(cd test2-checkout && $OSTREE commit -b test2 -s "with statoverride" --statoverride=../test-statoverride.txt)
+rm -rf test2-checkout
+$OSTREE checkout test2 test2-checkout
+test -u test2-checkout/abinary